#include "ZigbeeGWDevice.h"
#include "Protocol/Version2Protocol.h".h"
#include "version2device.h"
ZigbeeGWDevice::ZigbeeGWDevice(QObject *parent) :
    BaseInterface<ZigbeeGWDevice>(parent)
{

    qDebug()<<"zigbeeGW running";
    m_pInstance = this;
    zigbeeGWProtocol = new ZigbeeGWProtocol(this);
    this->registerProtocol(zigbeeGWProtocol);

    registerFuncHandler(ControlPointFunc::FunctionCode, &ZigbeeGWDevice::ControlPointFuncHandle);
    registerCmdHandler(ZigbeeGWDeviceJoinCmd::FunctionCode,ZigbeeGWDeviceJoinCmd::staticMetaObject, &ZigbeeGWDevice::ZigbeeGWDeviceJoinHandle);
    registerCmdHandler(ZigbeeGWSecurityInformationCmd::FunctionCode,ZigbeeGWSecurityInformationCmd::staticMetaObject, &ZigbeeGWDevice::ZigbeeGWSecurityInformationHandle);
    registerCmdHandler(ZigbeeGWInfraredCmd::FunctionCode,ZigbeeGWInfraredCmd::staticMetaObject, &ZigbeeGWDevice::ZigbeeLearnInfraredSuccessHandle);
    registerCmdHandler(ZigbeeGWDeviceQuitCmd::FunctionCode,ZigbeeGWDeviceQuitCmd::staticMetaObject, &ZigbeeGWDevice::ZigbeeGWDeviceQuitHandle);

}


void ZigbeeGWDevice::ControlPointFuncHandle(QSharedPointer<BaseFunc> sharedFunc)
{
    ControlPointFunc *pointControlFunc = qobject_cast<ControlPointFunc*>(sharedFunc.data());
    QList<ControlPointStruct> controlPointList;
    qDebug()<<"zigbeeGW controlpointhandle!";
    if(pointControlFunc->sourceDevice() == this->name())
    {
        controlPointList.append(pointControlFunc->sourcePointList());
        controlPointList.append(pointControlFunc->controlPointList());
    }
    else
    {
        controlPointList.append(pointControlFunc->sourcePointList());
        controlPointList.append(pointControlFunc->controlPointList());
    }
    if(controlPointList.isEmpty())
    {
       qDebug()<<"return";
        return;
    }
    Zigbee3ListXml *zigbee3ListXml = Zigbee3ListXml::getInstance();
    if((zigbee3ListXml->ZigbeeVersion().toHex().toInt(0,16))!=0x05)
    {
        //qDebug()<<"Not right Version";
        return;
    }
    QList<Zigbee3Struct> zigbee3List = zigbee3ListXml->zigbeeList(controlPointList);
    qDebug()<<"listsize="<<QString::number(zigbee3List.size());
    foreach(const Zigbee3Struct &zigbee,zigbee3List)
    {
        ZigbeeGWControlPointListCmd *zigbeeGWSendCmd = new ZigbeeGWControlPointListCmd();
        zigbeeGWSendCmd->setZigbee(zigbee);

        PortStruct target;
        foreach (const BasePort *port , m_portList)
        {
             if((port->portParam().type() == "UART" && port->portParam().name() == "Zigbee"))
             {
                 target = port->portParam();
             }
        }
       if(zigbeeGWSendCmd->toPackage().body().size()!=0)
       {
       emit sendDataSignal(target,zigbeeGWSendCmd->toPackage().body());
       }
    }

}

void ZigbeeGWDevice::ZigbeeGWDeviceJoinHandle(PortStruct source, QSharedPointer<BaseCmd> sharedCmd)
{
    Q_UNUSED(source);
    ZigbeeGWDeviceJoinCmd *DevicejoinData = qobject_cast<ZigbeeGWDeviceJoinCmd*>(sharedCmd.data());
    Zigbee3Struct zigbeeStruck;
    Zigbee3ListXml *zigbeeListXml = Zigbee3ListXml::getInstance();

    zigbeeStruck.setMac(DevicejoinData->Mac());
    zigbeeStruck.setNwk(DevicejoinData->Nwk());

    QByteArray data;
    data.clear();
    data.append(DevicejoinData->Nwk());
    data.append(DevicejoinData->Mac());
    qDebug()<<"new join try";
   if(zigbeeListXml->modify(1,zigbeeStruck)==true)
    {
    PortStruct target;
    foreach (const BasePort *port , m_portList)
    {
         if((port->portParam().type() == "UART" && port->portParam().name() == "RS485"))
         {
             target = port->portParam();
         }
    }
  //  emit sendDataSignal(target,data);


    LogicCloudDataFunc *logicCloudDataFunc=new  LogicCloudDataFunc();
    logicCloudDataFunc->setData(data);
    logicCloudDataFunc->setDataFunctionCode(0x46);
    logicCloudDataFunc->setSourceDevice(this->name());
    QSharedPointer<BaseFunc> sharedlogicCloudDataFuncFunc(logicCloudDataFunc);
    emit transferFuncSignal(sharedlogicCloudDataFuncFunc);
    Version2Protocol Version;
    QByteArray TestJoindata;
    Package package;
    package.setBody(data);
    package.setFunction(0x001B);
    TestJoindata=Version.generateData(package);
    emit sendDataSignal(target,TestJoindata);
    qDebug()<<"join zigbee3 now";
   }


}

void ZigbeeGWDevice::ZigbeeGWDeviceQuitHandle(PortStruct source, QSharedPointer<BaseCmd> sharedCmd)
{
    Q_UNUSED(source);
    ZigbeeGWDeviceQuitCmd *DevicejoinData = qobject_cast<ZigbeeGWDeviceQuitCmd*>(sharedCmd.data());
    Zigbee3Struct zigbeeStruck;
    Zigbee3ListXml *zigbeeListXml = Zigbee3ListXml::getInstance();

    zigbeeStruck.setMac(DevicejoinData->Mac());
    zigbeeStruck.setNwk(DevicejoinData->Nwk());

    QByteArray data;
    data.clear();
    data.append(DevicejoinData->Nwk());
    data.append((char)0x00);
//    data.append(DevicejoinData->Mac());
    qDebug()<<"new Quit try";
//   if(zigbeeListXml->modify(1,zigbeeStruck)==true)
//    if(zigbeeListXml->SetDelete(QString(DevicejoinData->Nwk()))==true)
//    {
    PortStruct target;
    foreach (const BasePort *port , m_portList)
    {
         if((port->portParam().type() == "UART" && port->portParam().name() == "RS485"))
         {
             target = port->portParam();
         }
    }
  //  emit sendDataSignal(target,data);


//    LogicCloudDataFunc *logicCloudDataFunc=new  LogicCloudDataFunc();
//    logicCloudDataFunc->setData(data);
//    logicCloudDataFunc->setDataFunctionCode(0x46);
//    logicCloudDataFunc->setSourceDevice(this->name());
//    QSharedPointer<BaseFunc> sharedlogicCloudDataFuncFunc(logicCloudDataFunc);
//    emit transferFuncSignal(sharedlogicCloudDataFuncFunc);
    Version2Protocol Version;
    QByteArray TestJoindata;
    Package package;
    package.setBody(data);
    package.setFunction(0x001d);
    TestJoindata=Version.generateData(package);
    emit sendDataSignal(target,TestJoindata);
    qDebug()<<"Quit zigbee3 now";
//   }


}



void ZigbeeGWDevice::ZigbeeGWSecurityInformationHandle(PortStruct source, QSharedPointer<BaseCmd> sharedCmd)
{
    Q_UNUSED(source);
    ZigbeeGWSecurityInformationCmd *SecurityData = qobject_cast<ZigbeeGWSecurityInformationCmd*>(sharedCmd.data());
    Zigbee3ListXml *zigbee3ListXml = Zigbee3ListXml::getInstance();
    if(zigbee3ListXml->ZigbeeVersion().toHex().toInt(0,16)!=5)
    {
        return ;
    }
    QByteArray nwk=SecurityData->Nwk();
    QList<Zigbee3Struct>zigbee3List=zigbee3ListXml->zigbee3List();
    quint16 yhdata=(SecurityData->Data().toHex().toUInt(0,16))&0x01;
    PortStruct target;
    foreach (const BasePort *port , m_portList)
    {
         if((port->portParam().type() == "UART" && port->portParam().name() == "RS485"))
         {
             target = port->portParam();
         }
    }
    QByteArray data;
    data.append(SecurityData->Nwk());
    data.append(yhdata);
    Version2Protocol Version;
    QByteArray TestJoindata;
    Package package;
    package.setBody(data);
    package.setFunction(0x001C);
    TestJoindata=Version.generateData(package);
    emit sendDataSignal(target,TestJoindata);
    foreach(const Zigbee3Struct &zigbee3Struct,zigbee3List)
    {
     //   qDebug()<<"A";
        if(zigbee3Struct.nwk()==nwk)
        {
            foreach(ControlPointStruct pointStruct,zigbee3Struct.pointList())
            {
                quint16 address;
                quint16 value=0;
                address=pointStruct.address();
                qDebug()<<"yhdata="<<QString::number(yhdata);
                qDebug()<<"data="<<QString::number(SecurityData->Data().toInt(0,16));
                switch(yhdata)
                {

                    case 0x01:value=0x01;break;
                    case 0x00:value=0x00;break;
                    default:return ;
                }
                if(zigbee3Struct.type()==0x03)
                {
                    switch(yhdata)
                    {

                        case 0x01:value=0x00;break;
                        case 0x00:value=0x01;break;
                        default:return ;
                    }
                }
                ControlPointFunc *pointControlFunc = new ControlPointFunc();
                ControlPointStruct sourcePoint;
                sourcePoint.setAddress(address);
                sourcePoint.setValue(value);
                QList<ControlPointStruct> sourcePointList;
                sourcePointList.append(sourcePoint);
                pointControlFunc->setSourceDevice(this->name());
                pointControlFunc->setSourcePointList(sourcePointList);

                QSharedPointer<BaseFunc> sharedPointControlFunc(pointControlFunc);
                emit transferFuncSignal(sharedPointControlFunc);          
            }
        }
    }
}


void ZigbeeGWDevice::ZigbeeLearnInfraredSuccessHandle(PortStruct source, QSharedPointer<BaseCmd> sharedCmd)
{
    Q_UNUSED(source);
    ZigbeeGWInfraredCmd *InfraredData = qobject_cast<ZigbeeGWInfraredCmd*>(sharedCmd.data());
    QByteArray Body=InfraredData->Data();
    quint16 function=Body.mid(5,1).toHex().toInt(0,16);
    Zigbee3InfraredXml *zigbee3InfraredXml = Zigbee3InfraredXml::getInstance();
    Zigbee3ListXml *zigbee3ListXml = Zigbee3ListXml::getInstance();
    QByteArray nwk;
    nwk.append(InfraredData->Nwk().mid(1,1));
    nwk.append(InfraredData->Nwk().mid(0,1));
    QList<Zigbee3Struct>zigbee3List=zigbee3ListXml->zigbee3List();
    foreach(const Zigbee3Struct &zigbee3Struct,zigbee3List)
    {
        qDebug()<<"zigbeenwk="<<zigbee3Struct.nwk();
        qDebug()<<"nwkdata="<<nwk;
        if(zigbee3Struct.nwk()==nwk)
        {
            if(function==0xdf)
            {
                QByteArray InfraredID;
                InfraredID=Body.mid(8,16);
                Zigbee3InfraredStruct zigbee3InfraredStruct;
                quint16 pointValue=(Body.mid(22,1).toHex().toInt(0,16)-1)*256+(Body.mid(23,1).toHex().toInt(0,16)-1);
                qDebug()<<"addr="<<DataTypeConver::formatString(InfraredID.mid(14,2));
                zigbee3InfraredStruct.m_mac=zigbee3Struct.mac();
                zigbee3InfraredStruct.m_nwk=zigbee3Struct.nwk();
                zigbee3InfraredStruct.m_PointValue=pointValue;
                zigbee3InfraredStruct.m_data=InfraredID;
                zigbee3InfraredXml->CopyInfrared.insert(pointValue,zigbee3InfraredStruct);
                QString valuedata=QString("%1").arg(pointValue,4,16,QLatin1Char('0'));
                QByteArray data;
                data.clear();
               qDebug()<<"nwk="<<DataTypeConver::formatString(zigbee3InfraredStruct.m_nwk);
                 qDebug()<<"addr="<<zigbee3InfraredStruct.m_PointValue;
               //  QString value=QString::number(zigbee3InfraredStruct.m_PointValue);
                data.append(zigbee3InfraredStruct.m_nwk);

                data.append(valuedata);

                LogicCloudDataFunc *logicCloudDataFunc=new  LogicCloudDataFunc();
                logicCloudDataFunc->setData(data);
                logicCloudDataFunc->setDataFunctionCode(0x5b);
                logicCloudDataFunc->setSourceDevice(this->name());
                QSharedPointer<BaseFunc> sharedlogicCloudDataFuncFunc(logicCloudDataFunc);
                emit transferFuncSignal(sharedlogicCloudDataFuncFunc);
            }
        }
    }
}
